import uuid
from django.shortcuts import render
from django.core.paginator import Paginator
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse, QueryDict
from django.views import View
from django.contrib import messages
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from mymall.settings import alipay
from commodity.models import CommodityDetail
from customer.models import Customer, ShoppingCar
from .models import Order


# Create your views here.
@method_decorator(login_required, name='dispatch')
class OrderView(View):
    def get(self, request):
        data = request.GET.dict()
        signature = data.pop("sign")  # 获取sign（支付宝返回的加密签证，sign 不能参与签名验证）
        res = alipay.verify(data, signature)  # 支付宝自带的校验方法，返回值为True或者False
        print(res)
        status = 2  # 设置状态标志，1为支付成功，2为支付失败
        if res:  # 支付成功
            status = 1

        # 修改订单状态
        # navicat查询，发现订单编号就是dict中的out_trade_no的值
        out_trade_no = data.pop('out_trade_no')
        order = Order.objects.filter(order_no=out_trade_no)[0]
        order.status = status
        order.save()
        return HttpResponseRedirect('/order/show/')

    def post(self, request):
        # 导入alipay对象,并调用统一收单下单并支付页面接口
        # 参考文档：https://opendocs.alipay.com/apis/api_1/alipay.trade.page.pay
        # python的uuid模块提供UUID类和函数uuid1(), uuid3(), uuid4(), uuid5() 来生成1, 3, 4, 5各个版本的UUID
        # 1基于时间戳；3基于名字的MD5散列值；4基于随机数；5基于名字的SHA-1散列值
        # 根据需要创建的订单模型字段，需要获取money则需要商品选项信息，
        post = request.POST
        if post.get('flag') == 'car':
            car_id = post.get('id')
            car = ShoppingCar.objects.get(id=car_id)
            option_id = car.options.split(' ')[0]
            subject = car.subject
            num = int(car.number)
            id = car.commodity_id
            car.delete()
        else:
            id = post.get('id')
            option_id = post.get('option_id')
            subject = post.get('subject')
            num = int(post.get('num'))

        order_no = str(uuid.uuid4())
        # 优化一：校验数据库是否存在商品选项数据
        option = CommodityDetail.objects.filter(id=option_id)
        if not option:
            messages.add_message(request, messages.WARNING, '数据库无此商品选项数据')
            return HttpResponseRedirect(request.path)
        money = option[0].price * num
        option[0].inventory = option[0].inventory - num
        option[0].save()
        commodity_id = id

        # 生成订单数据
        Order.objects.create(order_no=order_no, money=money, subject=subject, commodity_id=commodity_id,
                             user_id=request.user.customer.id)

        order_param = alipay.api_alipay_trade_page_pay(
            # 商户订单号
            # 由商家自定义，64个字符以内，仅支持字母、数字、下划线且需保证在商户端不重复。
            out_trade_no=order_no,
            # 订单总金额
            total_amount=money,
            # 订单标题
            # 注意：不可使用特殊字符，如 /，=，& 等。
            subject=subject,
            # 回调地址
            return_url='http://127.0.0.1:8000/order/alipay/'  # 当支付成功后，支付宝沙箱回调给服务端该url指向的get请求
        )
        # 拼接支付地址：支付宝网关 + 订单参数
        pay_url = 'https://openapi-sandbox.dl.alipaydev.com/gateway.do?' + order_param

        # return HttpResponseRedirect(pay_url)
        return JsonResponse({'data': pay_url})

    """
    https://openapi-sandbox.dl.alipaydev.com/gateway.do?app_id=9021000132614872&biz_content=%7B%22subject%22%3A%22%5Cu5f17%5Cu6d1b%5Cu4f0a%5Cu5fb7%5Cu539a%5Cu5e95%5Cu677f%5Cu978b%5Cu3002%7C%5Cu989c%5Cu8272%5Cu5206%5Cu7c7b%3A%5Cu73ab%5Cu7ea2%5Cu8272%5Cu3002%7C%5Cu5c3a%5Cu7801%3A37%5Cu3002%7C%22%2C%22out_trade_no%22%3A%22062bf0d8-46f9-454b-b664-9ab9bcc41162%22%2C%22total_amount%22%3A449.0%2C%22product_code%22%3A%22FAST_INSTANT_TRADE_PAY%22%7D&charset=utf-8&method=alipay.trade.page.pay&return_url=http%3A%2F%2F127.0.0.1%3A8000%2Forder%2Falipay%2F&sign_type=RSA2&timestamp=2023-11-23+20%3A53%3A22&version=1.0&sign=QDLG%2FQ0dh8BDc9oMbAn1ARKULkAlDfYoxxeeDR9ILNptT1HOiCx2NtBm%2FUQsfrdgUbDTwYXv6nfVa%2FoXA6LUxc7dCzBqiEgPsXgamRvouzYXMicpBaZLdW1LiGhdmnigTMA%2Fh6WH9W%2BO3DMV0cFaP%2FA7nw4VvOzNkVfRIjYsEu3Y3MlArBmn5jXOvIok7Aeuik3Kpon%2BmzWqP2q%2FHc17FZfUp3njO%2Bco9td3kWMXOExMvUahjF4IbPSgnjxm%2Fwlcbc%2BkfWbrI%2Ff%2BQz2KdeFF4rvJ3GuPFZWBNRhSfUJZ0dFdoZThRMc5gtiW8JQ%2F2fZkvjC2wxJQh%2FHhb%2BqfmwbLQQ%3D%3D
    """

    def put(self, request):
        data = QueryDict(request.body)
        id = data.get('id')
        order = Order.objects.get(id=id)
        order_param = alipay.api_alipay_trade_page_pay(
            # 商户订单号
            # 由商家自定义，64个字符以内，仅支持字母、数字、下划线且需保证在商户端不重复。
            out_trade_no=order.order_no,
            # 订单总金额
            total_amount=order.money,
            # 订单标题
            # 注意：不可使用特殊字符，如 /，=，& 等。
            subject=order.subject,
            # 回调地址
            return_url='http://127.0.0.1:8000/order/alipay/'  # 当支付成功后，支付宝沙箱回调给服务端该url指向的get请求
        )
        # 拼接支付地址：支付宝网关 + 订单参数
        pay_url = 'https://openapi-sandbox.dl.alipaydev.com/gateway.do?' + order_param

        # return HttpResponseRedirect(pay_url)
        return JsonResponse({'data': pay_url})


@method_decorator(login_required, name='dispatch')
class OrderShowView(View):
    def get(self, request):
        # 查询所有需要的订单数据
        order_list = Order.objects.filter(user=request.user.customer).order_by('-create_time')

        # 实现分页
        total_num = order_list.count()  # 总数据量
        page = request.GET.get('page', 1)  # 当前页码
        per_page = request.GET.get('per_page', 20)  # 每页数据条数

        paginator = Paginator(order_list, per_page, allow_empty_first_page=True)
        order_list = paginator.get_page(page)  # 每页显示数据，
        total_page = paginator.num_pages  # 总页数

        return render(request, 'order.html',
                      {
                          'order_list': order_list,
                          'total_page': total_page,
                          'page': page,
                          'per_page': per_page,
                          'total_num': total_num,
                      })  # 跳转到首页，订单页写好后，修改为跳转到订单页


